import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
 
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;


public class CreateXMLFile {
	private String sduration1,sduration2,sduration3,sduration4,
	sduration5,sduration6,sduration7,sduration8;
	
	private String sstate1,sstate2,sstate3,sstate4,sstate5,sstate6,
	sstate7,sstate8;
	
	private int[] time = new int[8];
	
	//Set up US road style in that you can turn right on red only way to do that is make the 
	//light green, they will break if they see any cars coming.
	
	private String[] state = {"ggrrrrggrrrr",
                             "rrrggrrrrggr",
                             "rrggrrrrggrr",
	                         "grrrrggrrrrg",
                             "rrrrrrggggrr",
                             "ggggrrrrrrrr",
                             "rrrggggrrrrr",
                             "grrrrrrrrggg"};
	
	public CreateXMLFile(Chromo X){
		int[] tempstate = new int[8];
		
		time[0] = X.BitToInt(X, 0, 7) + 1;
		sduration1 = Integer.toString(time[0]);
		tempstate[0] = X.BitToInt(X, 7, 10);
		
		time[1] = X.BitToInt(X, 10, 17) + 1;
		sduration2 = Integer.toString(time[1]);
		tempstate[1] = X.BitToInt(X, 17, 20);
		
		time[2] = X.BitToInt(X, 20, 27) + 1;
		sduration3 = Integer.toString(time[2]);
		tempstate[2] = X.BitToInt(X, 27, 30);
		
		time[3] = X.BitToInt(X, 30, 37) + 1;
		sduration4 = Integer.toString(time[3]);
		tempstate[3] = X.BitToInt(X, 37, 40);
		
		time[4] = X.BitToInt(X, 40, 47) + 1;
		sduration5 = Integer.toString(time[4]);
		tempstate[4] = X.BitToInt(X, 47, 50);
		
		time[5] = X.BitToInt(X, 50, 57) + 1;
		sduration6 = Integer.toString(time[5]);
		tempstate[5] = X.BitToInt(X, 57, 60);
		
		time[6] = X.BitToInt(X, 60, 67) + 1;
		sduration7 = Integer.toString(time[6]);
		tempstate[6] = X.BitToInt(X, 67, 70);
		
		time[7] = X.BitToInt(X, 70, 77) + 1;
		sduration8 = Integer.toString(time[7]);
		tempstate[7] = X.BitToInt(X, 77, 80);
		
		for(int i = 0;i < 8; i++){
			if(i == 0){
				sstate1=state[tempstate[0]];
			}else if(i == 1){
				sstate2=state[tempstate[1]];
			}else if(i == 2){
				sstate3=state[tempstate[2]];
			}else if(i == 3){
				sstate4=state[tempstate[3]];
			}else if(i == 4){
				sstate5=state[tempstate[4]];
			}else if(i == 5){
				sstate6=state[tempstate[5]];
			}else if(i == 6){
				sstate7=state[tempstate[6]];
			}else if(i == 7){
				sstate8=state[tempstate[7]];
			}
		}
		
		buildXML();
	}

	private void buildXML(){
		
		try{
		 
			DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
	 
			//root elements
			Document doc     = docBuilder.newDocument();
			Element add      = doc.createElement("add");
			doc.appendChild(add);

			Element tl_logic = doc.createElement("tl-logic");
			add.appendChild(tl_logic);
			
			Attr attrid = doc.createAttribute("id");
			attrid.setValue("Intersection");
			tl_logic.setAttributeNode(attrid);
			
			Attr attrtype = doc.createAttribute("type");
			attrtype.setValue("static");
			tl_logic.setAttributeNode(attrtype);
			
			Attr attrpgid = doc.createAttribute("programID");
			attrpgid.setValue("1");
			tl_logic.setAttributeNode(attrpgid);
			
			Attr attroffset = doc.createAttribute("offset");
			attroffset.setValue("0");
			tl_logic.setAttributeNode(attroffset);
			
			Element phase_1 = doc.createElement("phase");
			Attr attrduration_1 = doc.createAttribute("duration");
			//Set This from code
			attrduration_1.setValue(sduration1);
			phase_1.setAttributeNode(attrduration_1);
			
			Attr attrstate_1 = doc.createAttribute("state");
			//Set This from code
			attrstate_1.setValue(sstate1);
			phase_1.setAttributeNode(attrstate_1);
			
			tl_logic.appendChild(phase_1);
			
			Element phase_2 = doc.createElement("phase");
			Attr attrduration_2 = doc.createAttribute("duration");
			//Set This from code
			attrduration_2.setValue(sduration2);
			phase_2.setAttributeNode(attrduration_2);
			
			Attr attrstate_2 = doc.createAttribute("state");
			//Set This from code
			attrstate_2.setValue(sstate2);
			phase_2.setAttributeNode(attrstate_2);
			
			tl_logic.appendChild(phase_2);
			
			Element phase_3 = doc.createElement("phase");
			Attr attrduration_3 = doc.createAttribute("duration");
			//Set This from code
			attrduration_3.setValue(sduration3);
			phase_3.setAttributeNode(attrduration_3);
			
			Attr attrstate_3 = doc.createAttribute("state");
			//Set This from code
			attrstate_3.setValue(sstate3);
			phase_3.setAttributeNode(attrstate_3);
			
			tl_logic.appendChild(phase_3);
			
			Element phase_4 = doc.createElement("phase");
			Attr attrduration_4 = doc.createAttribute("duration");
			//Set This from code
			attrduration_4.setValue(sduration4);
			phase_4.setAttributeNode(attrduration_4);
			
			Attr attrstate_4 = doc.createAttribute("state");
			//Set This from code
			attrstate_4.setValue(sstate4);
			phase_4.setAttributeNode(attrstate_4);
			
			tl_logic.appendChild(phase_4);
			
			Element phase_5 = doc.createElement("phase");
			Attr attrduration_5 = doc.createAttribute("duration");
			//Set This from code
			attrduration_5.setValue(sduration5);
			phase_5.setAttributeNode(attrduration_5);
			
			Attr attrstate_5 = doc.createAttribute("state");
			//Set This from code
			attrstate_5.setValue(sstate5);
			phase_5.setAttributeNode(attrstate_5);
			
			tl_logic.appendChild(phase_5);
			
			Element phase_6 = doc.createElement("phase");
			Attr attrduration_6 = doc.createAttribute("duration");
			//Set This from code
			attrduration_6.setValue(sduration6);
			phase_6.setAttributeNode(attrduration_6);
			
			Attr attrstate_6 = doc.createAttribute("state");
			//Set This from code
			attrstate_6.setValue(sstate6);
			phase_6.setAttributeNode(attrstate_6);
			
			tl_logic.appendChild(phase_6);
			
			Element phase_7 = doc.createElement("phase");
			Attr attrduration_7 = doc.createAttribute("duration");
			//Set This from code
			attrduration_7.setValue(sduration7);
			phase_7.setAttributeNode(attrduration_7);
			
			Attr attrstate_7 = doc.createAttribute("state");
			//Set This from code
			attrstate_7.setValue(sstate7);
			phase_7.setAttributeNode(attrstate_7);
			
			tl_logic.appendChild(phase_7);
			
			Element phase_8 = doc.createElement("phase");
			Attr attrduration_8 = doc.createAttribute("duration");
			//Set This from code
			attrduration_8.setValue(sduration8);
			phase_8.setAttributeNode(attrduration_8);
			
			Attr attrstate_8 = doc.createAttribute("state");
			//Set This from code
			attrstate_8.setValue(sstate8);
			phase_8.setAttributeNode(attrstate_8);
			
			tl_logic.appendChild(phase_8);

			//Add line to tell SUMO to collect lane data statistics
			Element meanDataLane = doc.createElement("meandata-lane");
			Attr meanDataLaneId = doc.createAttribute("id");
			meanDataLaneId.setValue("laneStatistics");
			meanDataLane.setAttributeNode(meanDataLaneId);
			Attr meanDataLaneFrequency = doc.createAttribute("freq");
			meanDataLaneFrequency.setValue(Integer.toString(Parameters.meanLaneDataSampleTimeSeconds));
			meanDataLane.setAttributeNode(meanDataLaneFrequency);
			Attr meanDataLaneFile = doc.createAttribute("file");
			

			String output = Parameters.sumoOutputPath + Parameters.sumoLaneStatisticsOutputFile;
			meanDataLaneFile.setValue(output);
         
			meanDataLane.setAttributeNode(meanDataLaneFile);

			add.appendChild(meanDataLane);

			//write the content into xml file
			TransformerFactory transformerFactory = TransformerFactory.newInstance();
			Transformer transformer = transformerFactory.newTransformer();
			DOMSource source = new DOMSource(doc);
			StreamResult result =  new StreamResult(new File(Parameters.sumoNetworkRoutePath, Parameters.sumoAdditionalParamFile));
			transformer.transform(source, result);

	    }catch(ParserConfigurationException pce){
	    	pce.printStackTrace();
	    }catch(TransformerException tfe){
	    	tfe.printStackTrace();
	    }
	}
	
	public int[] getTime(){
		return time;
	}
}
